package sk.naive.talker;


import sk.naive.talker.util.Utils;

import javax.mail.*;
import javax.mail.Message;
import javax.mail.internet.*;
import java.util.*;

/**
 * MailSingleAccountHelper.
 *
 * @author <a href="mailto:virgo@naive.deepblue.sk">Richard "Virgo" Richter</a>
 * @version $Revision: 1.5 $ $Date: 2007-05-07 10:34:20 $
 */
public class MailSingleAccountHelper extends MailHelper {
	public static final String TPROP_MAIL_STORE_USER = "mailStoreUser";
	public static final String TPROP_MAIL_STORE_PASSWORD = "mailStorePassword";

	private Store store;
	private Folder sysFolder;
	private String lastMessageId;

	private Store getStore() throws MessagingException {
		if (store == null) {
			Session session = getSession();
			store = session.getStore("imap");
		}
		if (!store.isConnected()) {
			store.connect(
				getMailStoreHost(),
				(String) talker.getProperties().get(TPROP_MAIL_STORE_USER),
				(String) talker.getProperties().get(TPROP_MAIL_STORE_PASSWORD)
			);
		}
		return store;
	}

	private Folder getSystemFolder() throws MessagingException {
		getStore();
		if (sysFolder == null) {
			sysFolder = getStore().getFolder("INBOX");
		}
		if (!sysFolder.isOpen()) {
			sysFolder.open(Folder.READ_WRITE);
		}
		return sysFolder;
	}

	protected Folder getRealInbox(User user) throws MessagingException {
		Folder folder = getSystemFolder().getFolder(user.getLogin());
		if (!folder.exists()) {
			folder.create(Folder.HOLDS_MESSAGES | Folder.HOLDS_FOLDERS);
		}
		folder.open(Folder.READ_WRITE);
		return folder;
	}

	public void periodicCheck() throws MessagingException {
		Message[] messages = getSystemFolder().getMessages();
		for (Message message : messages) {
			if (lastMessageId != null && lastMessageId.equals(((MimeMessage) message).getMessageID())) {
				message.setFlag(Flags.Flag.DELETED, true);
				continue;
			}
			Set<String> recipients = new HashSet<String>();
			Address[] addresses = message.getRecipients(Message.RecipientType.TO);
			addRecipients(recipients, addresses);
			addresses = message.getRecipients(Message.RecipientType.CC);
			addRecipients(recipients, addresses);
			addresses = message.getRecipients(Message.RecipientType.BCC);
			addRecipients(recipients, addresses);
			processMessage(message, recipients);
		}
		getSystemFolder().expunge();
		super.periodicCheck();
	}

	private void addRecipients(Set<String> recipients, Address[] addresses) {
		if (addresses == null) {
			return;
		}
		for (Address address1 : addresses) {
			InternetAddress address = (InternetAddress) address1;
			String[] sa = address.getAddress().split("@", 2);
			if (sa.length < 2 || sa[1].equalsIgnoreCase(getTransportHost())) {
				recipients.add(sa[0]);
			}
		}
	}

	private void processMessage(Message message, Set<String> recipients) throws MessagingException {
		Message[] ma = new Message[]{message};
		for (String login : recipients) {
			User rec = talker.userFinder().findUserByLogin(login);
			if (rec == null) {
				Utils.warning("MailSingle.processMessage: recipient " + login + " does not exist");
				continue;
			}
			Folder f = getRealInbox(rec);
			message.getFolder().copyMessages(ma, f);
			f.close(false);
		}
		message.setFlag(Flags.Flag.DELETED, true);
		lastMessageId = ((MimeMessage) message).getMessageID();
	}
}
